import { computed, watch, ref } from 'vue'

import { buildUUID } from '@/utils/uuid'
// eslint-disable-next-line max-len
import type { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
import type {
  viewSpecKeyParam,
  specInfoParamList,
  specKeyParamList,
  specValue,
  specInfoBase,
} from '@/types/shop'
export default function (data: specInfoParamList[]) {
  const datas: specInfoParamList[] = data || []
  let globalTrees: Array<viewSpecKeyParam> = []
  const allTreeLength = ref(0)
  /**
   * 单元格合并字典
   * key  rowIndex-columnIndex
   * value [number, number]
   */
  const spanMergeDic = ref({})
  // 获取树
  function getGlobalTrees(): Array<viewSpecKeyParam> {
    return globalTrees
  }
  // 获取表头表头
  function getLabels(): String[] {
    return []
  }

  /**
   * 将数据转换为树
   */
  function initTree() {
    if (Array.isArray(datas) && datas.length >= 1) {
      // 存一组数据
      // const trees: Array<viewSpecKeyParam> = []
      datas.forEach((node: specInfoParamList) => {
        const {
          specKeyParamList,
          costPrice,
          num,
          price,
          specBarCode,
          specCode,
        } = node

        // 生成节点信息
        const infoBase: specInfoBase = {
          costPrice,
          num,
          price,
          specBarCode,
          specCode,
        }

        createTree(specKeyParamList, infoBase, globalTrees, 0)
      })
      // 生成table需要用到的合并数据
      initSpanMergeDic()
      console.log('allTreeLength =' + allTreeLength.value)
    }
  }
  /**
   * 通过横纵坐标获取合并数据
   * SpanMethodProps el-table的span-method 返回的数据结构
   */
  function mergeCellWithRowAndCol({
    row,
    column,
    rowIndex,
    columnIndex,
  }: SpanMethodProps) {}

  /**
   * 将传进来的 [{name: text, value : [{CSValue: ''}]}] 进行树的生成
   */
  function transformation(datas: any[]) {
    globalTrees = subTransformation(datas[0], datas, 0)
  }
  function subTransformation(data: any, datas: any[], index: number) {
    // item.specValue.value = data.value
    if (Array.isArray(data.value)) {
      return data.value.map((str: string) => {
        const item: viewSpecKeyParam = { text: '', specValue: { value: '' } }
        item.text = data.name
        item.specValue.value = str
        if (index < datas.length - 1) {
          item.subTreeSpecKeyParamList = subTransformation(
            datas[index + 1],
            datas,
            index + 1
          )
        } else {
          item.subTreeSpecKeyParamList = []
        }
        return item
      })
    } else {
      return null
    }
  }
  function initSpanMergeDic() {
    let allRowLength = 0
    const tmpSpanMergeDic = {}
    globalTrees.forEach((item: viewSpecKeyParam) => {
      // 第二层
      const { subTreeSpecKeyParamList } = item
      if (Array.isArray(subTreeSpecKeyParamList)) {
        let allRowLength2 = 0
        subTreeSpecKeyParamList.forEach((item2: viewSpecKeyParam) => {
          // 第三层 (目前第三层只有一层，所以先不进行编写)

          const count = getLastLevelCount(item2)
          // 计算spanMergeDic
          const key = getKey(allRowLength + allRowLength2, 1)
          // @ts-ignore：无法被执行的代码的错误
          tmpSpanMergeDic[key] = [count, 1]

          for (let index = 1; index < count; index++) {
            // 计算需要隐藏的宽度
            // @ts-ignore：无法被执行的代码的错误
            tmpSpanMergeDic[getKey(allRowLength + allRowLength2 + index)] = [
              0, 0,
            ]
          }
          // 计算第二层有多大
          allRowLength2 += count
        })
      }

      // 第一层
      const count = getLastLevelCount(item)

      // 计算spanMergeDic
      const key = getKey(allRowLength)
      // @ts-ignore：无法被执行的代码的错误
      tmpSpanMergeDic[key] = [count, 1]
      for (let index = 1; index < count; index++) {
        // 计算需要隐藏的宽度
        // @ts-ignore：无法被执行的代码的错误
        tmpSpanMergeDic[getKey(allRowLength + index)] = [0, 0]
      }

      // 计算整个树有多大
      allRowLength += count
    })

    allTreeLength.value = allRowLength
    spanMergeDic.value = tmpSpanMergeDic
    function getKey(a: number, b: number = 0): string {
      return `${a}-${b}`
    }
  }
  /**
   * 获取一个节点的
   * @param data 有多少个最次节点
   */
  function getLastLevelCount(data: viewSpecKeyParam) {
    const list = data.subTreeSpecKeyParamList
    if (Array.isArray(list) && list.length > 0) {
      const counts = list.map((item) => {
        const { subTreeSpecKeyParamList } = item
        if (subTreeSpecKeyParamList && subTreeSpecKeyParamList.length > 0) {
          const counts: any[] = subTreeSpecKeyParamList.map((e) => {
            return getLastLevelCount(e)
          })

          return arrayTotalToAll(counts)
        } else {
          return 1
        }
      })
      return arrayTotalToAll(counts)
    } else {
      return 1
    }
  }

  function getCellText(rowIndex: number, index: number) {
    let tmpIndex = 0
    let text = null
    for (let index = 0; index < globalTrees.length; index++) {
      const item = globalTrees[index]
      tmpIndex += item.subTreeSpecKeyParamList?.length || 0
      console.log('rrowIndex = ' + rowIndex + 'tmpIndex = ' + tmpIndex)
      if (rowIndex < tmpIndex) {
        text = item.text
        break
      }
    }
    return text
  }
  return {
    initTree,
    transformation,
    getGlobalTrees,
    getLastLevelCount,
    spanMergeDic,
    allTreeLength,
    getCellText,
  }
}
function arrayTotalToAll(array: number[]) {
  return array.reduce(function (a: number, b: number) {
    return parseInt(a) + parseInt(b)
  }, 0)
}
export interface User {
  id: string
  name: string
  amount1: string
  amount2: string
  amount3: number
}
export interface SpanMethodProps {
  row: User
  column: TableColumnCtx<User>
  rowIndex: number
  columnIndex: number
}
/**
 * 1. 第一步拿到数据结构后，转成树
 * 2. 合并cell和表格渲染用树形
 * 3. 树转tabel，table分配uuid,tree有新增 插入table。table只做增删
 * 4. 上传时树反转table
 */

function createTree(
  specKeyParamList: specKeyParamList[],
  infoBase: specInfoBase,
  trees: Array<viewSpecKeyParam>,
  index: number = 0,
  // 上级节点
  node?: viewSpecKeyParam
) {
  const item = specKeyParamList[index] as viewSpecKeyParam
  // 是否最终节点
  const isEnding: Boolean = specKeyParamList.length === index + 1
  // 是否能找到同级
  const specItem = findSameLevel(item, trees)

  // 1. 第一层没有就直接添加
  // 2. 后面的
  if (index === 0) {
    if (!specItem) trees.push(item)
    // node specItem 有值说明多节点，没有就从头开始传item
    createTree(specKeyParamList, infoBase, trees, index + 1, specItem || item)
    return
  } else if (node) {
    // 到最后一点，应该赋值给上级节点
    if (isEnding) {
      item.specInfoBase = infoBase
      if (!node.subTreeSpecKeyParamList) node.subTreeSpecKeyParamList = []
      node.subTreeSpecKeyParamList?.push(item)
    } else {
      console.log('specItem =' + JSON.stringify(specItem))
      if (specItem) {
        createTree(
          specKeyParamList,
          infoBase,
          specItem.subTreeSpecKeyParamList as Array<viewSpecKeyParam>,
          index + 1,
          item
        )
      } else {
        if (!node.subTreeSpecKeyParamList) node.subTreeSpecKeyParamList = []
        node.subTreeSpecKeyParamList?.push(item)
        // 兼容多层级。
        createTree(
          specKeyParamList,
          infoBase,
          node.subTreeSpecKeyParamList,
          index + 1,
          item
        )
      }
    }
  }
}

function addNode(node: specInfoParamList) {
  const { specKeyParamList, costPrice, num, price, specBarCode, specCode } =
    node

  // 生成节点信息
  const infoBase: specInfoBase = {
    costPrice,
    num,
    price,
    specBarCode,
    specCode,
  }

  // createTree(specKeyParamList, infoBase, globalTrees, 0)
}
// 因为可能有重复，所以只找一季
function checkSubNode(text: String, tree: viewSpecKeyParam) {}

// 判断同级是否能找到这个参数
function findSameLevel(node: viewSpecKeyParam, nodes: viewSpecKeyParam[]) {
  const spec = nodes.find((item) => {
    // 名称和属性一致才是同一个节点
    const b =
      node.specValue.value === item.specValue.value && node.text === item.text
    return b
  })
  return spec || null
}
